package com.lab.service.impl;

import com.lab.common.Constants;
import com.lab.dto.WeeklyReportContentDTO;
import com.lab.dto.WeeklyReportDTO;
import com.lab.entity.Member;
import com.lab.entity.WeeklyReport;
import com.lab.entity.WeeklyReportContent;
import com.lab.mapper.WeeklyReportContentMapper;
import com.lab.mapper.WeeklyReportMapper;
import com.lab.service.MemberService;
import com.lab.service.WeeklyReportService;
import com.lab.vo.WeeklyReportVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 周报管理服务实现类
 */
@Service
public class WeeklyReportServiceImpl implements WeeklyReportService {

    private static final Logger log = LoggerFactory.getLogger(WeeklyReportServiceImpl.class);

    @Autowired
    private WeeklyReportMapper weeklyReportMapper;

    @Autowired
    private WeeklyReportContentMapper weeklyReportContentMapper;

    @Autowired
    private MemberService memberService;

    /**
     * 根据ID查询周报
     */
    @Override
    public WeeklyReport getById(Integer id) {
        log.info("根据ID查询周报：{}", id);
        if (id == null) {
            throw new RuntimeException("周报ID不能为空");
        }
        
        WeeklyReport weeklyReport = weeklyReportMapper.getById(id);
        if (weeklyReport == null) {
            throw new RuntimeException("周报不存在");
        }
        
        return weeklyReport;
    }

    /**
     * 根据成员ID查询周报列表
     */
    @Override
    public List<WeeklyReport> getByMemberId(Integer memberId) {
        log.info("根据成员ID查询周报列表：{}", memberId);
        if (memberId == null) {
            throw new RuntimeException("成员ID不能为空");
        }
        
        return weeklyReportMapper.getByMemberId(memberId);
    }

    /**
     * 根据成员ID查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByMemberId(Integer memberId) {
        log.info("根据成员ID查询周报及其内容：{}", memberId);
        if (memberId == null) {
            throw new RuntimeException("成员ID不能为空");
        }
        
        return weeklyReportMapper.getReportWithContentsByMemberId(memberId);
    }

    /**
     * 根据成员名称查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByMemberName(String memberName) {
        log.info("根据成员名称查询周报及其内容：{}", memberName);
        if (memberName == null || memberName.trim().isEmpty()) {
            throw new RuntimeException("成员名称不能为空");
        }
        
        // 1. 根据成员名称查询成员信息
        List<Member> members = memberService.getByName(memberName);
        if (members.isEmpty()) {
            return new ArrayList<>(); // 没有找到成员，返回空列表
        }
        
        // 2. 遍历成员列表，查询每个成员的周报信息
        List<WeeklyReportVO> result = new ArrayList<>();
        for (Member member : members) {
            List<WeeklyReportVO> reports = getReportWithContentsByMemberId(member.getId());
            result.addAll(reports);
        }
        
        return result;
    }

    /**
     * 根据角色类型查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByRoleType(String roleType) {
        log.info("根据角色类型查询周报及其内容：{}", roleType);
        if (roleType == null || roleType.trim().isEmpty()) {
            throw new RuntimeException("角色类型不能为空");
        }
        
        // 验证角色类型是否合法（前端或后端）
        if (!Constants.ROLE_FRONTEND.equals(roleType) && !Constants.ROLE_BACKEND.equals(roleType)) {
            throw new RuntimeException("角色类型不合法，只能是前端或后端");
        }
        
        return weeklyReportMapper.getReportWithContentsByRoleType(roleType);
    }

    /**
     * 根据周数查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByWeekWithoutPagination(Integer reportWeek, Integer reportYear) {
        log.info("根据周数查询周报及其内容：第{}周，年份{}", reportWeek, reportYear);
        
        // 参数验证
        if (reportWeek == null || reportYear == null) {
            throw new RuntimeException("周数和年份不能为空");
        }
        
        // 验证周数范围（1-52）
        if (reportWeek < 1 || reportWeek > 52) {
            throw new RuntimeException("周数必须在1-52之间");
        }
        
        // 验证年份合理性（例如：不能小于2000年，不能大于当前年份+1）
        int currentYear = java.time.Year.now().getValue();
        if (reportYear < 2000 || reportYear > currentYear + 1) {
            throw new RuntimeException("年份不合法");
        }
        
        return weeklyReportMapper.getReportWithContentsByWeekWithoutPagination(reportWeek, reportYear);
    }
    
    /**
     * 分页查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByWeekAndPage(Integer reportWeek, Integer reportYear, Integer page, Integer pageSize) {
        log.info("根据周数分页查询周报及其内容：第{}周，年份{}，第{}页，每页{}条", reportWeek, reportYear, page, pageSize);
    
        // 参数验证
        if (reportWeek == null || reportYear == null) {
            throw new RuntimeException("周数和年份不能为空");
        }
    
        // 验证周数范围（1-52）
        if (reportWeek < 1 || reportWeek > 52) {
            throw new RuntimeException("周数必须在1-52之间");
        }
    
        // 验证年份合理性（例如：不能小于2000年，不能大于当前年份+1）
        int currentYear = java.time.Year.now().getValue();
        if (reportYear < 2000 || reportYear > currentYear + 1) {
            throw new RuntimeException("年份不合法");
        }
    
        if (page == null || page < 1) {
            throw new RuntimeException("页码必须大于等于1");
        }
        if (pageSize == null || pageSize < 1) {
            throw new RuntimeException("每页条数必须大于等于1");
        }
        if (pageSize > 100) {
            throw new RuntimeException("每页条数不能超过100");
        }
    
        // 计算偏移量
        int offset = (page - 1) * pageSize;
    
        return weeklyReportMapper.getReportWithContentsByPage(offset, pageSize);
    }
    
    /**
     * 分页查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByPage(Integer page, Integer pageSize) {
        log.info("分页查询周报及其内容：第{}页，每页{}条", page, pageSize);
        
        // 参数验证
        if (page == null || page < 1) {
            throw new RuntimeException("页码必须大于等于1");
        }
        if (pageSize == null || pageSize < 1) {
            throw new RuntimeException("每页条数必须大于等于1");
        }
        if (pageSize > 100) {
            throw new RuntimeException("每页条数不能超过100");
        }
        
        // 计算偏移量
        int offset = (page - 1) * pageSize;
        
        return weeklyReportMapper.getReportWithContentsByPage(offset, pageSize);
    }
    
    /**
     * 根据角色类型分页查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByRoleTypeAndPage(String roleType, Integer page, Integer pageSize) {
        log.info("根据角色类型分页查询周报及其内容：角色类型{}，第{}页，每页{}条", roleType, page, pageSize);
        
        // 参数验证
        if (roleType == null || roleType.trim().isEmpty()) {
            throw new RuntimeException("角色类型不能为空");
        }
        if (!Constants.ROLE_FRONTEND.equals(roleType) && !Constants.ROLE_BACKEND.equals(roleType)) {
            throw new RuntimeException("角色类型不合法，只能是前端或后端");
        }
        if (page == null || page < 1) {
            throw new RuntimeException("页码必须大于等于1");
        }
        if (pageSize == null || pageSize < 1) {
            throw new RuntimeException("每页条数必须大于等于1");
        }
        if (pageSize > 100) {
            throw new RuntimeException("每页条数不能超过100");
        }
        
        // 计算偏移量
        int offset = (page - 1) * pageSize;
        
        return weeklyReportMapper.getReportWithContentsByRoleTypeAndPage(roleType, offset, pageSize);
    }
    
    /**
     * 根据成员ID分页查询周报及其内容（完整信息）
     */
    @Override
    public List<WeeklyReportVO> getReportWithContentsByMemberIdAndPage(Integer memberId, Integer page, Integer pageSize) {
        log.info("根据成员ID分页查询周报及其内容：成员ID{}，第{}页，每页{}条", memberId, page, pageSize);
        
        // 参数验证
        if (memberId == null) {
            throw new RuntimeException("成员ID不能为空");
        }
        if (page == null || page < 1) {
            throw new RuntimeException("页码必须大于等于1");
        }
        if (pageSize == null || pageSize < 1) {
            throw new RuntimeException("每页条数必须大于等于1");
        }
        if (pageSize > 100) {
            throw new RuntimeException("每页条数不能超过100");
        }
        
        // 计算偏移量
        int offset = (page - 1) * pageSize;
        
        return weeklyReportMapper.getReportWithContentsByMemberIdAndPage(memberId, offset, pageSize);
    }
    
    /**
     * 根据周数和年份删除周报信息（包括关联的周报内容）
     */
    @Override
    public Integer deleteByWeekAndYear(Integer reportWeek, Integer reportYear) {
        log.info("根据周数和年份删除周报信息：第{}周，年份{}", reportWeek, reportYear);
        
        // 参数验证
        if (reportWeek == null || reportYear == null) {
            throw new RuntimeException("周数和年份不能为空");
        }
        
        // 验证周数范围（1-52）
        if (reportWeek < 1 || reportWeek > 52) {
            throw new RuntimeException("周数必须在1-52之间");
        }
        
        // 验证年份合理性（例如：不能小于2000年，不能大于当前年份+1）
        int currentYear = java.time.Year.now().getValue();
        if (reportYear < 2000 || reportYear > currentYear + 1) {
            throw new RuntimeException("年份不合法");
        }
        
        // 执行删除操作
        Integer deletedCount = weeklyReportMapper.deleteByWeekAndYear(reportWeek, reportYear);
        log.info("成功删除{}条周报记录", deletedCount);
        
        return deletedCount;
    }

    @Override
    @Transactional
    public void addWeeklyReportWithContent(Integer memberId, WeeklyReportDTO weeklyReportDTO, WeeklyReportContentDTO weeklyReportContentDTO) {
        log.info("添加周报及其内容：{}", weeklyReportDTO.toString());

        // 1. 检查是否已存在相同成员、年份、周数的周报
        WeeklyReport existingReport = weeklyReportMapper.getByMemberIdAndYearAndWeek(
                memberId,
                weeklyReportDTO.getReportYear(),
                weeklyReportDTO.getReportWeek()
        );

        if (existingReport != null) {
            throw new RuntimeException("该成员本周周报已提交，请勿重复提交");
        }

        // 2. 插入周报主表
        WeeklyReport weeklyReport = new WeeklyReport();
        weeklyReport.setMemberId(memberId);
        weeklyReport.setRoleType(weeklyReportDTO.getRoleType());
        weeklyReport.setReportYear(weeklyReportDTO.getReportYear());
        weeklyReport.setReportWeek(weeklyReportDTO.getReportWeek());
        weeklyReportMapper.insert(weeklyReport);

        // 获取新插入周报的ID
        Integer reportId = weeklyReport.getId();
        if (reportId == null) {
            throw new RuntimeException("周报主表插入失败，无法获取ID");
        }

        // 3. 插入周报内容表
        WeeklyReportContent weeklyReportContent = new WeeklyReportContent();
        weeklyReportContent.setReportId(reportId);
        weeklyReportContent.setContent(weeklyReportContentDTO.getContent());
        weeklyReportContentMapper.insert(weeklyReportContent);

        log.info("周报及其内容添加成功，周报ID：{}", reportId);
    }
}